import {
	mapGetters
} from "vuex";

export default (app, option = {}) => {
	const mixins = {
		data() {
			return {
				selectionList: [],
				data: [],
				form: {},
				params: {},
				loading: false,
				api: require(`@/api/${option.name}`),
				option: require(`@/option/${option.name}`).default,
				page: {
					pageSizes: [10, 30, 50, 100, 200],
					pageSize: 10
				},
			}
		},
		computed: {
			...mapGetters(['userInfo', 'permission', 'roles']),
			ids() {
				const ids = [];
				this.selectionList.forEach(ele => {
					ids.push(ele[this.rowKey]);
				});
				return ids.join(",");
			},
			bindVal() {
				return {
					ref: 'crud',
					option: this.option,
					data: this.data,
					tableLoading: this.loading
				}
			},
			onEvent() {
				return {
					'on-load': this.getList,
					'row-save': this.rowSave,
					'row-update': this.rowUpdate,
					'row-del': this.rowDel,
					'selection-change': this.selectionChange,
					'refresh-change': this.refreshChange,
					'date-change': this.dateChange,
					'search-change': this.searchChange,
					'search-reset': this.searchChange
				}
			},
			rowKey() {
				return this.option.rowKey || option.rowKey || 'id'
			}
		},
		methods: {
			getList() {
				const callback = () => {
					this.loading = true;
					this.api[option.list || 'getList'](this.page.currentPage, this.page.pageSize, this.params)
						.then(res => {
							let data;
							if (option.res) {
								data = option.res(res.data);
							} else {
								data = res.data.data;
							}
							this.page.total = data[option.total || 'total'] || 0;
							this.data = data[option.records || 'records'];
							if (this.listAfter) {
								this.listAfter(data);
							}
							this.loading = false;
						})
				}
				if (this.listBefore) {
					this.listBefore();
				}
				callback();
			},
			rowSave(row, done, loading) {
				const callback = () => {
					delete this.form.params;
					this.api[option.add || 'add'](this.form).then((data) => {
						this.getList();
						if (this.addAfter) {
							this.addAfter(data);
						} else {
							this.$message.success('新增成功');
						}
						done();
					}).catch(() => {
						loading();
					})
				}
				if (this.addBefore) {
					this.addBefore();
				}
				callback();
			},
			rowUpdate(row, index, done, loading) {
				const callback = () => {
					delete this.form.params;
					this.api[option.update || 'update'](this.form).then((data) => {
						this.getList();
						if (this.updateAfter) {
							this.updateAfter(data);
						} else {
							this.$message.success('更新成功');
						}
						done();
					}).catch(() => {
						loading();
					})
				}
				if (this.updateBefore) {
					this.updateBefore();
				}
				callback();
			},
			rowDel(row, index) {
				const callback = () => {
					this.api[option.del || 'remove'](row[this.rowKey], row).then((data) => {
						this.getList();
						if (this.delAfter) {
							this.delAfter(data, row, index)
						} else {
							this.$message.success('删除成功');
						}
					})
				}
				if (this.delBefore) {
					this.delBefore();
					callback();
				} else {
					this.$confirm('确定将选择数据删除?', '提示', {
						confirmButtonText: '确定',
						cancelButtonText: '取消',
						type: 'warning'
					}).then(() => {
						callback();
					})
				}
			},
			handleDelete() {
				if (this.selectionList.length === 0) {
					this.$message.warning("请选择至少一条数据");
					return;
				}
				this.$confirm("确定将选择数据删除?", {
						confirmButtonText: "确定",
						cancelButtonText: "取消",
						type: "warning"
					})
					.then(() => {
						this.api[option.del || 'remove'](this.ids).then((data) => {
							this.getList();
							if (this.delMultiAfter) {
								this.delMultiAfter(data, this.ids);
							} else {
								this.$message.success('删除成功');
							}
						});
					});
			},
			searchChange(params, done) {
				if (done) done();
				if (this.validatenull(params)) {
					Object.keys(this.params).forEach(ele => {
						if (!['createTime_dategt', 'createTime_datelt'].includes(ele)) {
							delete this.params[ele];
						}
					})
				} else {
					Object.keys(params).forEach(ele => {
						if (this.validatenull(params[ele])) {
							delete this.params[ele];
							delete params[ele];
						}
					})
				}
				this.params = Object.assign(this.params, params);
				this.page.currentPage = 1;
				this.getList();
			},
			dateChange(date) {
				if (date) {
					this.params.createTime_dategt = date[0];
					this.params.createTime_datelt = date[1];
				} else {
					delete this.params.createTime_dategt;
					delete this.params.createTime_datelt;
				}
				this.page.currentPage = 1;
				this.getList();
			},
			selectionChange(list) {
				this.selectionList = list;
			},
			selectionClear() {
				this.selectionList = [];
				this.$refs.crud.toggleSelection();
			},
			refreshChange() {
				this.getList();
			},
			openNewtab(url) {
				this.$router.push(url)
			}
		}
	}
	app.mixins = app.mixins || [];
	app.mixins.push(mixins);
	return app;
}
